package makabakaquestionnaire.zutsoftware.utils.workWx;

import makabakaquestionnaire.zutsoftware.utils.JsonUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 使用HttpClientUtil工具类
 */
@Component
public class HttpClientUtil {
    /**
     * post请求，携带着创建成员的数据
     */

    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    public static String METHOD_GET = "Get";

    public static String METHOD_POST = "Post";


    private static RedisTemplate stringRedisTemplate;

    @Autowired
    @Qualifier("redisTemplate")
    public void setStringRedisTemplate(RedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 执行企业微信接口方法
     *
     * @param key    AccessToken的key值
     * @param url    接口地址
     * @param json   json数据
     * @param method 请求方式 Get or Post
     * @return jsontomapd的MAP，大概是和postman返回的一长串信息
     */
    public static Map<String, Object> wxRequest(String key, String url, String json, String method) {
        Map<String, Object> mapData = new HashMap<>();
        int num = 0;
        boolean flag = false;
        while (num < 3) {
            try {
                num++;
                if (stringRedisTemplate.hasKey(key)) {
                    url = url.replace(key, (CharSequence) stringRedisTemplate.opsForValue().get(key));
                    System.out.println(url);
                    String jsonData = null;
                    if (method.equals(METHOD_GET)) {
                        jsonData = get(url);
                    } else if (method.equals(METHOD_POST)) {
                        jsonData = post(url, json);
                    }
                    mapData = JsonUtil.toMap(jsonData);
                    int errCode = Integer.parseInt(mapData.get("errcode").toString());

                    if (errCode == 0) {//0：正常
                        return mapData;
                    } else if (errCode == 42001) { // access_token过期
                        stringRedisTemplate.delete(key); //删除key
                        logger.info("key:{},access token过期", key);
                    } else if (errCode == 60111 || errCode == 60104 || errCode == 40029 || errCode == 60103) {
                        /**
                         * 60111：userid not found
                         * 60104：mobile existed
                         * 40029: invalid code
                         */
                        logger.info("key:{},url:{},json:{},method:{},msg:{}", key, url, json, method, jsonData);
                        return mapData;
                    } else {
                        flag = true;
                        logger.info("key:{},url:{},json:{},method:{},msg:{}", key, url, json, method, jsonData);
                    }
                }
                if (flag == false) {
                    mapData = WXAPIUtil.getAccessToken(key);
                    if (mapData != null) {

                        stringRedisTemplate.opsForValue().set(key, mapData.get("access_token").toString(),
                                Integer.parseInt(mapData.get("expires_in").toString()), TimeUnit.SECONDS);
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                logger.error("wxRequest error:{}", ex.getMessage());
                logger.error("wxRequest key:{},url:{},json:{}.method:{}", key, url, json, method);
            }
        }

        mapData.put("errcode", -1000);
        mapData.put("errmsg", "未获取到信息");
        return mapData;
    }

    /**
     * 发送get请求
     *
     * @param url
     * @return
     */
    public static String get(String url) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)   //设置连接超时时间
                .setConnectionRequestTimeout(5000) // 设置请求超时时间
                .setSocketTimeout(5000)
                .setRedirectsEnabled(true)//默认允许自动重定向
                .build();
        //发送get请求
        HttpGet request = new HttpGet(url);
        //对get请求进行设置
        request.setConfig(requestConfig);
        HttpResponse response = null;
        try {
            response = httpClient.execute(request);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //get response into String
        String temp = "";
        try {
            HttpEntity entity = response.getEntity();
            temp = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
        }

        return temp;

    }

    public static String post(String url, String json) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = new DefaultHttpClient();
            httpPost = new HttpPost(url);

            StringEntity entity = new StringEntity(json, "utf-8");//解决中文乱码问题
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }
}
